
#include <string.h>
#include "../lib/level_time_sampling.h"
#include "../lib/byte_bit.h"

#define IDLE_LEVLE		1
#define PULSE_LEVLE		!IDLE_LEVLE


#define DECODE_BIT_0			0
#define DECODE_BIT_1			1
#define DECODE_BIT_SYNC			2
#define DECODE_BIT_END			3
#define DECODE_BIT_ERROR		4

#define IR_TICK_TIME_IN_US			40UL						//40us/tick

#define SYNC_PULSE_TIME_TICK		6000/IR_TICK_TIME_IN_US		
#define SYNC_IDLE_TIME_TICK			7320/IR_TICK_TIME_IN_US

#define BIT0_PULSE_TIME_TICK		530/IR_TICK_TIME_IN_US
#define BIT0_IDLE_TIME_TICK			(2000-530)/IR_TICK_TIME_IN_US

#define BIT1_PULSE_TIME_TICK		530/IR_TICK_TIME_IN_US
#define BIT1_IDLE_TIME_TICK			(4000-530)/IR_TICK_TIME_IN_US

#define END_PULSE_TIME_TICK			530/IR_TICK_TIME_IN_US
#define END_IDLE_TIME_TICK			(8000-530)/IR_TICK_TIME_IN_US	

#define ALLOW_ERR_PERCENT			30UL

//repeat: PULSE 9000us + IDLE 2200us PULSE 560us + IDLE 96000us
//1 SYNC + 32 BIT + 1 END + repeat + repeat ....

static LEVEL_TIME_SAMPLING_STRUCT ir_rec;
static uint16_t pulse_tick_time_buff = 0;
static uint8_t bit_count = 0;
static uint8_t (*bsp_ir_receive_hal_read_level_callbakc)(void) = 0;

uint8_t bsp_ir_receive_finish_receive_falg = 0;
uint8_t bsp_ir_receive_buff[8] = {0};
uint8_t bsp_ir_receive_buff_len = 0;
void (*bsp_ir_receive_receive_finish_callbakc)(void) = 0;

static uint8_t decode_bit_pwm(uint16_t pulse_tick_time, uint16_t idle_tick_time)
{
	if((pulse_tick_time <= SYNC_PULSE_TIME_TICK + ((SYNC_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(pulse_tick_time >= SYNC_PULSE_TIME_TICK - ((SYNC_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time <= SYNC_IDLE_TIME_TICK + ((SYNC_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time >= SYNC_IDLE_TIME_TICK - ((SYNC_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))){
		return DECODE_BIT_SYNC;
	}
	
	if((pulse_tick_time <= BIT0_PULSE_TIME_TICK + ((BIT0_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(pulse_tick_time >= BIT0_PULSE_TIME_TICK - ((BIT0_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time <= BIT0_IDLE_TIME_TICK + ((BIT0_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time >= BIT0_IDLE_TIME_TICK - ((BIT0_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))){
		return DECODE_BIT_0;
	}

	if((pulse_tick_time <= BIT1_PULSE_TIME_TICK + ((BIT1_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(pulse_tick_time >= BIT1_PULSE_TIME_TICK - ((BIT1_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time <= BIT1_IDLE_TIME_TICK + ((BIT1_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time >= BIT1_IDLE_TIME_TICK - ((BIT1_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))){
		return DECODE_BIT_1;
	}
	
	if((pulse_tick_time <= END_PULSE_TIME_TICK + ((END_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(pulse_tick_time >= END_PULSE_TIME_TICK - ((END_PULSE_TIME_TICK*ALLOW_ERR_PERCENT)/100))
	&&(idle_tick_time >= END_IDLE_TIME_TICK - ((END_IDLE_TIME_TICK*ALLOW_ERR_PERCENT)/100))){
		return DECODE_BIT_END;
	}
	
	return DECODE_BIT_ERROR;
}

static void finish_callback_handler(LEVEL_TIME_SAMPLING_STRUCT* ir)
{
	uint8_t rec_bit;
	
	if(ir_rec.state.last_level != ir_rec.state.current_level){	//edge has be detected
		if(ir_rec.state.last_level == PULSE_LEVLE){
			pulse_tick_time_buff = ir_rec.count;
		}
		else{
			rec_bit = decode_bit_pwm(pulse_tick_time_buff, ir_rec.count);
		}
	}
	else{														//timeout
		if(ir_rec.state.last_level == IDLE_LEVLE){
			rec_bit = DECODE_BIT_ERROR;
		}
	}
	level_time_sampling_reset_counter(&ir_rec);
	
	if(rec_bit == DECODE_BIT_SYNC){
		bit_count = 0;
		bsp_ir_receive_buff_len = 0;
	}
	else if((rec_bit == DECODE_BIT_0)||(rec_bit == DECODE_BIT_1)){
		if(bit_to_byte_lsb_frist(&(bsp_ir_receive_buff[bsp_ir_receive_buff_len]), &bit_count, rec_bit) == 1){
			bsp_ir_receive_buff_len++;
			if(bsp_ir_receive_buff_len >= 5){
				bit_count = 0;
				bsp_ir_receive_buff_len = 0;
				memset(bsp_ir_receive_buff, 0, 8);
			}
		}
	}
	else if(rec_bit == DECODE_BIT_END){
		if(bsp_ir_receive_buff_len > 0){
			bsp_ir_receive_finish_receive_falg = 1;
			if(bsp_ir_receive_receive_finish_callbakc != 0){
				bsp_ir_receive_receive_finish_callbakc();
			}
		}
		bit_count = 0;
		bsp_ir_receive_buff_len = 0;
	}
	else{
		bit_count = 0;
		bsp_ir_receive_buff_len = 0;
	}
}

/********************************************************
#include "jxos_public.h"
#include <string.h>
uint8_t temp[256] = {0};
uint8_t ii = 0;
uint8_t start = 0;
static void print_time(LEVEL_TIME_SAMPLING_STRUCT* ir)
{
	uint8_t rec_bit;
	uint8_t l_p = 0;
		
	if((ir_rec.state.last_level == PULSE_LEVLE)
		&&(ir_rec.count > 5000/40)){
		ii = 0;
		memset(temp, 0, 256);
		start = 1;
	}
	if(start == 1){
		temp[ii] = ir_rec.state.last_level;
		ii++;
		temp[ii] = (uint8_t)(ir_rec.count);
		ii++;
		temp[ii] = (uint8_t)(ir_rec.count>>8);	
//		ringbuff_write_data(&temp_buff, 1, &(ir_rec.state));
//		ringbuff_write_data(&temp_buff, 2, &(ir_rec.count));
//		sys_debug_print_task_user_print_str("l:");
//		sys_debug_print_task_user_print_int(ir_rec.state.last_level);
//		sys_debug_print_task_user_print_str(" t:");
//		sys_debug_print_task_user_print_int(ir_rec.count);
//		sys_debug_print_task_user_print_str("\r\n");
		ii++;
		if(ii >= 254){
**********************************************************************
		while(1){
			pulse_ = temp[l_p+2];
			pulse_ <<= 8;
			pulse_ += temp[l_p+1];
			idle_ = temp[l_p+5];
			idle_ <<= 8;
			idle_ += temp[l_p+4];
			rec_bit = decode_bit_pwm(pulse_, idle_);

			if(rec_bit == DECODE_BIT_SYNC){
				bit_count = 0;
				bsp_ir_receive_buff_len = 0;
			}
			else if((rec_bit == DECODE_BIT_0)||(rec_bit == DECODE_BIT_1)){
				if(bit_to_byte_lsb_frist(&(bsp_ir_receive_buff[bsp_ir_receive_buff_len]), &bit_count, rec_bit) == 1){
					bsp_ir_receive_buff_len++;
					if(bsp_ir_receive_buff_len >= 8){
						bit_count = 0;
						bsp_ir_receive_buff_len = 0;
						memset(bsp_ir_receive_buff, 0, 8);
					}
				}
			}
			else if(rec_bit == DECODE_BIT_END){
				if(bsp_ir_receive_buff_len > 0){
					bsp_ir_receive_finish_receive_falg = 1;
					if(bsp_ir_receive_receive_finish_callbakc != 0){
						bsp_ir_receive_receive_finish_callbakc();
					}
				}
				bit_count = 0;
				bsp_ir_receive_buff_len = 0;
			}
			else{
				bit_count = 0;
				bsp_ir_receive_buff_len = 0;
			}
			l_p += 6;
			if(l_p >= 254){
				break;
			}
		}
**********************************************************************
			ii = 0;
			start = 0;
		}
	}
	level_time_sampling_reset_counter(&ir_rec);	
}
********************************************************/

void bsp_ir_receive_tick_handler(void)		//50us
{
	if(bsp_ir_receive_finish_receive_falg == 1){
		return;
	}
	level_time_sampling_tick_handler(&ir_rec, bsp_ir_receive_hal_read_level_callbakc());
}

void bsp_ir_receive_init(void (*bsp_ir_receive_hal_init_callbakc_handler)(void),
						uint8_t (*bsp_ir_receive_hal_read_level_callbakc_handler)(void))
{
	if(bsp_ir_receive_hal_init_callbakc_handler != 0){
		bsp_ir_receive_hal_init_callbakc_handler();
	}
	
	bsp_ir_receive_hal_read_level_callbakc = bsp_ir_receive_hal_read_level_callbakc_handler;
	
	pulse_tick_time_buff = 0;
	bit_count = 0;
	bsp_ir_receive_buff_len = 0;
	memset(bsp_ir_receive_buff, 0, 8);
	
//	level_time_sampling_init(&ir_rec, print_time);
	level_time_sampling_init(&ir_rec, finish_callback_handler);
	
}